package com.sofwin.aspect;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sofwin.Constants;
import com.sofwin.Log;
import com.sofwin.pojo.OperatorLog;
import com.sofwin.pojo.SysUser;
import com.sofwin.service.OperatorLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * @packageName: com.sofwin.aspect
 * @author: andyliu
 * @date: 2022/8/16 10:16
 * @email 115176513@qq.com
 * @description: TODO
 */
@Component
@Aspect
public class LogAspect {
    @Autowired
    private OperatorLogService operatorLogService;

    @AfterReturning(pointcut = "a()",returning = "result")
    public void afterReturnning(JoinPoint joinPoint,Object result) throws JsonProcessingException {
        handler(1,result,joinPoint);
        // 操作状态1成功
    }
    @AfterThrowing(pointcut = "a()",throwing = "ex")
    public void afterThrowing(JoinPoint point,Throwable ex) throws JsonProcessingException {
        handler(0,ex,point);
    }
    public void handler(Integer status,Object result,JoinPoint joinPoint) throws JsonProcessingException {
        MethodSignature signature =(MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();// 当前请求执行的方法
        Log log = method.getAnnotation(Log.class);
        String module = log.module();
        int operatorType = log.operatorType();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        // session
        Map parameterMap = request.getParameterMap();// 请求参数
        ObjectMapper objectMapper =new ObjectMapper();
        String requestURI = request.getRequestURI();
        String requestMethod = request.getMethod();
        // request 请求参数
        HttpSession session = request.getSession();
        SysUser user = (SysUser)session.getAttribute(Constants.CURRENT_USER);

        String operatorMethod = method.getName();// 操作方法
        OperatorLog operatorLog = new OperatorLog();

        operatorLog.setOperAddr(request.getRemoteHost()+request.getRemotePort());
        operatorLog.setModule(module);
        operatorLog.setRequestMethod(operatorMethod);
        operatorLog.setOperMethod(requestMethod);
        operatorLog.setOperType(operatorType);
        operatorLog.setOperStatus(status);
        operatorLog.setRemoteIp(request.getRemoteHost());
        operatorLog.setRequestParams(objectMapper.writeValueAsString(parameterMap));
        operatorLog.setRequestUrl(requestURI);
        operatorLog.setResponseData(objectMapper.writeValueAsString(result));
        operatorLog.setUserId(user.getId());
        operatorLogService.saveLog(operatorLog);
    }
    @Pointcut("@annotation(com.sofwin.Log)")
    public void a(){

    }
}
